package com.think.admin.web.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.think.admin.model.dto.role.RoleDTO;
import com.think.admin.model.param.role.RoleParam;
import com.think.admin.model.param.role.SetRoleResourceParam;
import com.think.admin.model.query.RoleQuery;
import com.think.admin.web.mapper.RoleMapper;
import com.think.admin.web.service.IRoleResourceService;
import com.think.admin.web.service.IRoleService;
import com.think.admin.web.service.IUserRoleService;
import com.think.common.enums.StateEnum;
import com.think.common.exception.SysException;
import com.think.common.param.UpdateBatchParam;
import com.think.common.utils.ResultUtil;
import com.think.common.utils.SysUtils;
import com.think.common.web.service.impl.SuperServiceImpl;
import com.think.dao.entity.Role;
import com.think.dao.entity.RoleResource;
import com.think.dao.entity.UserRole;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author xwj
 * @since 2019-04-08
 */
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = SysException.class)
public class RoleServiceImpl extends SuperServiceImpl<RoleMapper, Role> implements IRoleService {
    private final IUserRoleService userRoleService;
    private final IRoleResourceService roleResourceService;

    @Override
    public HttpEntity selectPage(Page<RoleDTO> page, RoleQuery roleQuery) {
        return ResultUtil.success(page.setRecords(baseMapper.selectPageRole(page, roleQuery)));
    }

    @Override
    public HttpEntity createOrUpdate(RoleParam roleParam) {
        // 提取ID
        String id = roleParam.getId();

        // 查重，角色名称唯一
        int roleNameCount = this.lambdaQuery().eq(Role::getRoleName, roleParam.getRoleName())
                .ne(SysUtils.isNotEmpty(id), Role::getId, id).count();
        if (0 != roleNameCount) {
            throw new SysException("角色名称已存在，请重试");
        }

        // roleParam 转换为 role
        Role role = roleParam.convert(Role.class);

        // 添加
        boolean saveIsSuccess = this.saveOrUpdate(role);
        if (saveIsSuccess) {
            // 重建用户角色缓存
            userRoleService.resetUserRole();
            return ResultUtil.success();
        } else if (SysUtils.isNotEmpty(id)) {
            return ResultUtil.updateError();
        } else {
            return ResultUtil.createError();
        }
    }

    @Override
    public HttpEntity updateState(UpdateBatchParam updateBatchParam) {
        // 非空判断
        if (SysUtils.isEmpty(updateBatchParam)) {
            return ResultUtil.requestParamError();
        }

        // 参数提取，非空判断
        StateEnum state = updateBatchParam.getState();
        List<String> idList = updateBatchParam.getIdList();
        if (SysUtils.isEmpty(state) || SysUtils.isEmpty(idList)) {
            return ResultUtil.requestParamError();
        }

        // 更新
        boolean updateIsSuccess = this.lambdaUpdate()
                .set(Role::getState, state)
                .set(Role::getGmtModified, LocalDateTime.now())
                .in(Role::getId, idList).update();
        if (updateIsSuccess) {
            // 重建用户角色缓存
            userRoleService.resetUserRole();
            return ResultUtil.success();
        } else {
            return ResultUtil.updateError();
        }
    }

    @Override
    public HttpEntity delete(List<String> idList) {
        // 非空判断
        if (SysUtils.isEmpty(idList)) {
            return ResultUtil.requestParamError();
        }

        // 批量删除
        boolean deleteSuccess = this.lambdaUpdate().in(Role::getId, idList).remove();
        if (!deleteSuccess) {
            return ResultUtil.deleteError();
        }

        // 删除该角色的用户关联
        userRoleService.lambdaUpdate().in(UserRole::getRoleId, idList).remove();

        // 删除该角色的权限关联
        roleResourceService.lambdaUpdate().in(RoleResource::getRoleId, idList).remove();

        // 重建用户角色缓存
        userRoleService.resetUserRole();

        // 重建角色资源缓存
        roleResourceService.resetRoleResource();

        // 返回
        return ResultUtil.deleteSuccess();
    }

    @Override
    public HttpEntity setRoleResource(SetRoleResourceParam setRoleResourceParam) {
        // 非空判断
        if (SysUtils.isEmpty(setRoleResourceParam)) {
            return ResultUtil.requestParamError();
        }

        // 参数提取，非空判断
        List<String> roleIdList = setRoleResourceParam.getRoleIdList();
        List<String> resourceIdList = setRoleResourceParam.getResourceIdList();
        if (SysUtils.isNull(roleIdList)) {
            return ResultUtil.requestParamError();
        }

        // 删除
        roleResourceService.lambdaUpdate().in(RoleResource::getRoleId, roleIdList).remove();

        // 资源ID列表为空，直接返回
        if (SysUtils.isEmpty(resourceIdList)) {
            // 重建角色资源缓存
            roleResourceService.resetRoleResource();
            return ResultUtil.success();
        }

        // 重建角色资源关联
        List<RoleResource> list = new ArrayList<>();
        roleIdList.forEach(roleId -> resourceIdList.forEach(resourceId -> {
            RoleResource roleResource = new RoleResource();
            roleResource.setRoleId(roleId);
            roleResource.setResourceId(resourceId);
            list.add(roleResource);
        }));
        if (true == roleResourceService.saveBatch(list)) {
            // 重建角色资源缓存
            roleResourceService.resetRoleResource();
            return ResultUtil.success();
        } else {
            throw new SysException("重建角色资源关联失败");
        }
    }
}
